home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- main.c: Copyright (c) Kevin Hammond 1993. All rights reserved.
-
- This is the main module for the Gofer Mac interface.
-
- The routines in this module handle initialisation, the main event loop
- and top-level event dispatching.
-
- *****************************************************************************/
-
- #pragma segment GMain
-
- #include "mac.h"
- #include <AppleEvents.h>
- #include <Errors.h>
-
- CursHandle ibeamcurs, watchcurs; /* Ibeam and Watch cursors */
- CursHandle gccurs; /* Cursor used during GC */
- CCrsrHandle gccursc; /* Colour version of above */
-
- EventRecord myEvent; /* Main event record */
- Boolean WNEAvailable = FALSE; /* WaitNextEvent available */
- Boolean CCAvailable = FALSE; /* Colour Cursors available */
- Boolean CIAvailable = FALSE; /* Colour Icons available */
- Boolean HasAppleEvents = FALSE; /* Supports System-7 AppleEvents */
- Boolean inForeground = TRUE; /* Are we in the background? */
- Boolean MemoryInstalledOK = FALSE; /* True once the memory's been initialised */
- Boolean GoferInitialised = FALSE; /* True once the interface is initialised */
- Boolean InterpreterInitialised = FALSE; /* True once Gofer's completely initialised */
-
- short systemVersion = 0x0000; /* System software version */
- short goferWDRefNum = 0; /* Gofer's working directory's refnum */
- short gofervol = 0; /* Gofer's "real" vRefNum */
- long goferdirID = 0; /* Gofer's "real" dirID */
- short goferresfile = -1; /* Gofer's resource file no. */
-
- static RgnHandle cursorRgn; /* Cursor region for WaitNextEvent */
-
- Boolean quit = FALSE; /* Set when finished */
-
- extern jmp_buf catch_error; /* The error jump buffer, used by longjmp */
-
- Bool USER_ABORT = FALSE; /* Has the user Pressed CMD-. */
- extern Boolean EOFread; /* Has the user Pressed CMD-ENTER */
- extern Boolean HandlingEvents; /* Is the Programmer Handling Events in Gofer */
-
- int HeapPC = DEFAULT_HEAP_PERCENTAGE; /* % Remaining memory for Heap */
- unsigned MinMemSize = DEFAULT_MIN_MEM_SIZE; /* Minimum Memory to run in */
- #define MIN_INIT_SIZE 320000 /* Minimum Memory to start up */
-
- unsigned ExtraStack = 0; /* How much extra stack to reserve on startup */
-
-
- char *undoBuffer=NIL; /* The characters which can be "undone" */
-
-
- /* Forward declarations */
-
- Boolean cursorkey(); /* Is this key a cursor key */
- extern OSType preftype; /* The type of the Gofer Preferences file */
- extern Boolean scrapVisible; /* Is the scrap (clipboard) window visible */
- extern DescType savemethod; /* How to do global saves */
-
-
- /*****************************************************************************
-
- Interacting with our environment.
-
- ******************************************************************************/
-
-
- /*
- ObtainEnvironment determines whether WaitNextEvent etc are available.
- System 7 should use Gestalt -- KH
- */
-
- #define WNETrapNumber 0xA860 /* WaitNextEvent trap */
- #define CCTrapNumber 0xAA1B /* GetCCursor trap */
- #define CITrapNumber 0xAA1E /* GetCIcon trap */
-
- extern savedir(short vrefnum, long dirID, Boolean reset);
-
- ObtainEnvironment()
- {
- SysEnvRec environ;
- Str255 goferVolName;
-
- /* If no default volume, use Gofer's folder */
- // if(GetVol(goferVolName, &goferWDRefNum) != noErr)
- if(TRUE)
- {
- FCBPBRec fcb;
- fcb.ioNamePtr = NULL;
- fcb.ioCompletion = NULL;
- fcb.ioVRefNum = 0;
- fcb.ioRefNum = goferresfile;
- fcb.ioFCBIndx = 0;
- PBGetFCBInfo(&fcb,FALSE);
- gofervol = fcb.ioFCBVRefNum;
- goferdirID = fcb.ioFCBParID;
- }
- else
- (void) getwdinfo(goferWDRefNum, &gofervol, &goferdirID);
-
- savedir(gofervol,goferdirID,TRUE);
-
- (void) SysEnvirons(1, &environ); /* How old is this system? */
-
- if (environ.machineType < 0) /* Negative if really old */
- {
- WNEAvailable = FALSE;
- CCAvailable = FALSE;
- CIAvailable = FALSE;
- HasAppleEvents = FALSE;
- systemVersion = 0x0000;
- }
- else
- {
- WNEAvailable = TrapAvailable(WNETrapNumber, ToolTrap);
- CCAvailable = TrapAvailable(CCTrapNumber, ToolTrap);
- CIAvailable = TrapAvailable(CITrapNumber, ToolTrap);
- systemVersion = environ.systemVersion;
-
- HasAppleEvents = systemVersion >= 0x0700;
- if(HasAppleEvents)
- InstallAEHandlers();
- }
-
- if (WNEAvailable)
- cursorRgn = NewRgn();
- }
-
-
-
- /*****************************************************************************
-
- General event-handling code.
-
- ******************************************************************************/
-
-
- /*
- Disk Insertion event.
-
- Format the disk if an unformatted disk is inserted.
- */
-
-
- void DoDiskEvent()
- {
- if (HiWord(myEvent.message) != noErr)
- {
- myEvent.where.h = ((qd.screenBits.bounds.right - qd.screenBits.bounds.left) / 2) - (304 / 2);
- myEvent.where.v = ((qd.screenBits.bounds.bottom - qd.screenBits.bounds.top) / 3) - (104 / 2);
-
- InitCursor();
- (void) DIBadMount(myEvent.where, myEvent.message);
- }
- }
-
-
-
- /*
- Handle menus -- whether from mouse downs or keys.
- */
-
- void DoMenu(result,modifiers)
- long result;
- short modifiers;
- {
- short menu = HiWord(result);
- short item = LoWord(result);
-
- if (menu != 0 && item != 0)
- {
- Handle_Gofer_Menu(menu, item, modifiers);
- drawcursor(myEvent, FALSE);
- AdjustMenus(FALSE);
- }
- }
-
-
-
- /*
- Window Zooming -- Macintosh System 3.2 or Later.
- */
-
-
- void DoZoom(whichWindow, code)
- WindowPtr whichWindow;
- short code;
- {
- if (whichWindow != NIL)
- {
- if (TrackBox(whichWindow, myEvent.where, code) == TRUE)
- {
- GrafPtr saveport;
-
- GetPort(&saveport);
- SetPort(whichWindow);
- EraseRect(&whichWindow->portRect);
- ZoomWindow(whichWindow, code, TRUE);
- SetPort(saveport);
-
- ResizeTheWindow(whichWindow);
- }
- }
- }
-
-
-
- /*
- Window resizing.
- */
-
-
- void DoGrow(whichWindow)
- WindowPtr whichWindow;
- {
- Rect OldRect;
- Rect GrowRect;
-
- long growResult;
- short newWidth, newHeight;
-
- if (whichWindow != NIL)
- {
- /* Remember previous rectangle */
- OldRect = whichWindow->portRect;
-
- /* Set the grow rectangle -- minimum 100x64; "infinite" maximum */
- SetRect(&GrowRect, 100, 64, 32767, 32767);
-
- /* Get user input */
- growResult = GrowWindow(whichWindow, myEvent.where, &GrowRect);
- newWidth = LoWord(growResult);
- newHeight = HiWord(growResult);
-
- /* If the new size is different from the previous one, resize the window appropriately */
- if ( (newWidth != 0 && newHeight != 0)
- && (newWidth != (OldRect.right - OldRect.left) || newHeight != (OldRect.bottom - OldRect.top)) )
- {
- GrafPtr saveport;
-
- GetPort(&saveport);
- SetPort(whichWindow);
- EraseRect(&whichWindow->portRect);
- InvalRect(&whichWindow->portRect);
- SetPort(saveport);
-
- SizeWindow(whichWindow, newWidth, newHeight, TRUE);
- ResizeTheWindow(whichWindow);
- }
- }
- }
-
-
-
- /*
- Move a window.
- */
-
- DoDrag(whichWindow)
- WindowPtr whichWindow;
- {
- Rect screenRect = qd.screenBits.bounds;
-
- SelectWindow(whichWindow);
-
- DragWindow(whichWindow, myEvent.where, &screenRect);
-
- MoveTheWindow(whichWindow);
- }
-
-
-
- /*
- Handle a press in a goaway box.
- */
-
- DoGoAway(whichWindow)
- WindowPtr whichWindow;
- {
- int windex;
-
- /*
- NB: This will not work for user-defined windows -- something
- more sophisticated is needed.
- */
- if (TrackGoAway(whichWindow,myEvent.where))
-
- /* Normal Gofer window */
- if((windex = findMyWindow(whichWindow))!=ILLEGAL_WINDOW)
- {
- if(myEvent.modifiers&optionKey)
- IconiseWindow(windex);
-
- else if (closethewindow(windex,"closing"))
- /* SKIP */;
- }
-
- /* Desk accessory */
- else if (((WindowPeek)whichWindow)->windowKind < 0)
- {
- CloseDeskAcc(((WindowPeek)whichWindow)->windowKind);
- thefrontwindow = ILLEGAL_WINDOW;
- }
-
- /* User-defined window */
- else
- {
- HideWindow(whichWindow);
- thefrontwindow = ILLEGAL_WINDOW;
- }
- }
-
-
-
- /*
- Handle a mouse click in the body of a window.
-
- Select the window if it's not the front window.
- Handle the mouse click after selecting the window
- only if the window is iconic (so select and drag is
- one operation rather than two for iconic windows).
- */
-
- DoInContent(whichWindow)
- WindowPtr whichWindow;
- {
- int windex = findMyWindow(whichWindow);
- if(!iconic(windex) && whichWindow != FrontWindow())
- SelectWindow(whichWindow);
- else
- {
- SetPort(whichWindow);
- DoTheWindow(whichWindow,&myEvent);
- }
- }
-
-
-
- /*
- Handle window update events.
- */
-
- void DoUpdate()
- {
- WindowPtr whichWindow = (WindowPtr)myEvent.message;
-
- UpdateTheWindow(whichWindow);
- }
-
-
-
- /*
- Handle window activation/deactivation.
- */
-
-
- void DoActivate()
- {
- /* Copy scrap whenever we become active */
- if (thefrontwindow == ILLEGAL_WINDOW)
- {
- TEFromScrap();
- loadscrap();
- }
-
- ActivateTheWindow((WindowPtr)myEvent.message,
- (myEvent.modifiers & activeFlag) != 0);
- drawcursor(myEvent,TRUE);
- }
-
-
-
- /*
- Handle an OS event, such as MultiFinder suspend/resume.
- */
-
- void DoOSEvent()
- {
- if((myEvent.message & osEvtMessageMask) == SuspResEvt)
- {
- inForeground = (myEvent.message & resumeFlag) != 0;
-
- if (inForeground)
- {
- /* Resume Gofer */
- WindowPtr frontwp;
-
- /* We only copy the System scrap to the TextEdit scrap if we're requested to */
- if (myEvent.message & convertClipboardFlag)
- {
- TEFromScrap();
- loadscrap();
- }
-
- /* If the scrap has been hidden, then show it */
- if ( scrapVisible && !((WindowPeek)WINDOW(scrap))->visible )
- ShowWindow(WINDOW(scrap));
-
- /* Activate the frontmost window if there is one and it belongs to us */
- frontwp = FrontWindow();
- if (frontwp != NIL && ((WindowPeek)frontwp)->windowKind > 0)
- ActivateTheWindow(FrontWindow(),TRUE);
- }
- else
- {
- /* Suspend Gofer */
- if(thefrontwindow != ILLEGAL_WINDOW)
- ActivateTheWindow(WINDOW(thefrontwindow),FALSE);
-
- if(scrapVisible)
- HideWindow(WINDOW(scrap));
- }
- AdjustMenus(FALSE);
- }
- }
-
-
- /*
- Handle a high-level Apple Event, such as open application,
- print document etc.
-
- System-7 specific.
- */
-
- void DoHighLevelEvent()
- {
- OSErr resultCode;
-
- resultCode = AEProcessAppleEvent(&myEvent);
- if (resultCode != noErr)
- {
- char resultStr[10];
- sprintf(resultStr,"%u",resultCode);
- paramtext("",resultStr,"","");
- StopAlert(Res_AppleEvent_Failed_Alert,NIL);
- }
- else
- AdjustMenus(FALSE);
- }
-
-
-
- /* K and M define memory sizes for convenience when setting heap etc. */
-
- #define K 1024
- #define M K*K
-
- #define MASTER_BLOCKS 5 /* How many extra blocks of handles to allocate. This is a guess */
-
- InitMemory()
- {
- long maxblock; /* Largest block during startup */
- unsigned heapsize; /* Heap size as determined during initialisation */
- int i;
-
- /* Set the stack space according to the amount of heap available */
-
- heapsize = GetApplLimit() - ApplicZone();
-
- if(ExtraStack == 0)
- ExtraStack = heapsize > 2*M? heapsize/15:
- heapsize > 1*M? 32*K:
- heapsize > 800*K? 16*K:
- heapsize > 600*K? 8*K:
- heapsize > 400*K? 4*K:
- 0*K;
-
- if(ExtraStack > 0)
- SetApplLimit(GetApplLimit()-ExtraStack);
-
- for(i=0;i<MASTER_BLOCKS;++i)
- MoreMasters(); /* Allow more handles */
- MaxApplZone(); /* Extend the heap up to its limit */
-
- /* Before even trying to start up, check our memory size */
- if((maxblock=MaxBlock()) < MIN_INIT_SIZE)
- {
- SysBeep(3);
- exit(1);
- }
- }
-
-
-
- /*****************************************************************************
-
- The main Program.
-
- ******************************************************************************/
-
-
- extern Boolean running_interpreter; /* Is the interpreter running? */
- static Boolean drawncursor = FALSE; /* Don't redraw the cursor if drawing the cursor has triggered an update! */
- static Point lastMousePosn; /* Where the mouse was last time */
-
-
- main()
- {
- /* NB: DON'T DECLARE ANY shorts/floats/Booleans here -- Gofer will choke on them! */
-
- long maxblock; /* Largest block during startup */
- int err; /* Error code from longjmp */
-
- goferresfile = CurResFile(); /* Record the application resource file */
-
- InitResData(); /* Set up global constants */
-
- InitMemory(); /* Initialise Memory Parameters */
-
-
- /* Initialise the Macintosh Managers */
-
- InitGraf((Ptr) &qd.thePort); /* Quickdraw */
- InitFonts(); /* Font Manager */
- InitWindows(); /* Window Manager */
- InitMenus(); /* Menu Manager */
- TEInit(); /* Text Edit */
- InitDialogs(NIL); /* Dialog Manager */
- InitCursorCtl(NIL); /* Spinning Cursors */
-
-
- ObtainEnvironment(); /* Find the current setup */
-
- FlushEvents (everyEvent,0 ); /* Clear all outstanding events */
- InitCursor(); /* Set the arrow cursor */
-
- Init_Gofer_Menus(); /* Initialise the menu bar */
-
-
- /*
- Check for ridiculously low memory.
- NB: Don't use FatalError here -- that jumps to catch_error,
- which is undefined at this point!
- */
-
- if((maxblock = MaxBlock()) < MinMemSize)
- {
- /*
- Don't declare error as a char array: it consumes stack permanently
- even if there's enough memory, and if not quadword aligned, can cause
- a crash during evaluation (in gcCStack)!
- */
-
- char *error = malloc(50);
-
- if(error == NULL)
- Error("Fatal ","Not enough memory to run MacGofer");
-
- else
- {
- sprintf(error,"MacGofer needs at least %uK free heap to run",MinMemSize/1024);
- Error("Fatal ",error);
- }
-
- exit(1);
- }
-
-
- /*
- This is the re-entry point for errors during initialisation.
- catch_error must be initialised before *any* Gofer memory allocation.
- */
-
- if((err=setjmp(catch_error)) ==0) /* Return here on failure during init */
- Init_Gofer(); /* Gofer initialisation */
-
- /* There's some duplication here */
- else if(!InterpreterInitialised)
- {
- RestorePrefs(TRUE); /* Restore all preferences, including toggles */
-
- InitOptionMenu(); /* Initialse the options menu from these prefs */
-
- if(GoferInitialised)
- {
- writeNewLine(); /* In case we were in the middle of a line */
- printPrompt();
- }
-
- /* If we couldn't even install the Heap, let the user know! */
- if(!MemoryInstalledOK && !quit)
- StopAlert(Res_MemoryNotInitialised_Alert,NIL);
-
- else
- ResetInterpreter(); /* Reset the interpreter */
-
- InterpreterInitialised = MemoryInstalledOK;
- }
- else
- {
- /*
- This is the re-entry point for errors during evaluation etc.
- */
-
- // if(MemoryInstalledOK && (err=setjmp(catch_error)) !=0) /* Return here on failure */
- // {
- if(HandlingEvents)
- useprojectresfile(FALSE,TRUE); /* Forget any loaded resources */
-
- windowtofront(worksheet); /* Bring the worksheet back to the front */
-
- writeNewLine(); /* In case we were in the middle of a line */
-
- /* This error is special: we can't call printf if we don't have any stack!! */
-
- if(err == 25)
- mprintf("Error: the Macintosh stack collided with the heap\n");
-
- printPrompt(); /* Output a prompt */
-
- HideMenus(FALSE); /* Restore the menus */
- HiliteMenu(0); /* Clear the menu bar in case "Loading" */
-
- HideAllWindows(FALSE); /* Restore our windows */
-
- ResetInterpreter(); /* Reset the interpreter */
-
- }
-
- running_interpreter = FALSE;
-
- ResetCursor(); /* Reset the cursor from a watch cursor */
-
- if(TEHANDLE(worksheet) != NIL)
- TEActivate(TEHANDLE(worksheet)); /* In case the worksheet insertion point got lost */
-
- resetinput(); /* Reset the terminal IO */
-
- AdjustMenus(TRUE); /* Reset the menus as if activating */
-
- SetPt(&lastMousePosn,0,0); /* Clear the last mouse position */
-
- FlushKeyEvents(); /* Handle any pent-up keyboard events */
-
- while (!quit) /* Repeat the event loop until quit is TRUE */
- eventloop(everyEvent);
-
- SaveHiddenPrefs(); /* Finally, save the hidden preferences */
-
- }
-
-
-
- /*
- One Cycle of the event loop.
- */
-
-
-
- eventloop(evtmask)
- int evtmask;
- {
- getnextevent(evtmask);
-
- if (inForeground && thefrontwindow != ILLEGAL_WINDOW && isEditWindow(thefrontwindow))
- TEIdle(TEHANDLE(thefrontwindow)); /* Blink the cursor */
-
- /*
- Draw a cursor appropriate to the mouse location.
- WaitNextEvent will notify us if we need to change the cursor.
- Don't draw if the event is an update caused by the last
- cursor draw or if the mouse hasn't moved between events.
- */
-
- drawncursor &= myEvent.what == updateEvt;
-
- if (!drawncursor)
- {
- if(!EqualPt(myEvent.where,lastMousePosn))
- {
- drawcursor(myEvent, TRUE);
- SetPt(&lastMousePosn,myEvent.where.h,myEvent.where.v);
- }
- drawncursor = TRUE;
- }
-
- switch (myEvent.what)
- {
- short code;
- WindowPtr whichWindow;
-
- case mouseDown :
- code = FindWindow(myEvent.where, &whichWindow);
-
- switch (code)
- {
- case inMenuBar :
- {
- long result;
- SetModifiedMenus(myEvent.modifiers);
- result = MenuSelect(myEvent.where);
- DoMenu(result,myEvent.modifiers);
- }
- break;
-
- case inDrag :
- DoDrag(whichWindow);
- break;
-
- case inGrow :
- DoGrow(whichWindow);
- break;
-
- case inZoomIn :
- case inZoomOut :
- DoZoom(whichWindow,code);
- break;
-
- case inGoAway :
- DoGoAway(whichWindow);
- AdjustMenus(FALSE);
- break;
-
- case inContent :
- DoInContent(whichWindow);
- AdjustMenus(FALSE);
- break;
-
- case inSysWindow :
- SystemClick(&myEvent, whichWindow);
- AdjustMenus(FALSE);
- break;
-
- default:
- break;
- }
- break;
-
- case keyDown: /* Key inputs */
- case autoKey: /* and auto repeats */
- DoKeyEvent(&myEvent,thefrontwindow,TRUE);
- break;
-
- case updateEvt : /* Update event for a window */
- DoUpdate();
- break;
-
- case diskEvt : /* Disk inserted event */
- DoDiskEvent();
- break;
-
- case activateEvt : /* Window activated event */
- DoActivate();
- break;
-
- case osEvt:
- DoOSEvent();
- break;
-
- case kHighLevelEvent:
- DoHighLevelEvent();
- break;
-
- default:
- break;
-
- }
- }
-
-
- /*
- Abstracted GetNextEvent/WaitNextEvent
- */
-
- getnextevent(eventmask)
- int eventmask;
- {
- /* Use WaitNextEvent if this is available -- this version blinks the cursor */
-
- if(running_interpreter && !EventAvail(eventmask,&myEvent))
- return;
-
- if (WNEAvailable)
- WaitNextEvent(eventmask, &myEvent, GetCaretTime(), cursorRgn);
- else
- {
- /* Handle Desk accessories, if necessary. */
- SystemTask();
- GetNextEvent(eventmask, &myEvent);
- }
- }
-
-
- /*
- Terminate Gofer unless cancelled.
- */
-
- Boolean Terminate_Gofer()
- {
- return(closeallwindows());
- }
-
-
-
- /*
- Program Initialisation.
-
- Get the files to open or print, and open the standard
- application windows (worksheet, scrap etc.) if running under
- Sys 6 or earlier.
-
- Just initialise the cursor resources under System 7.
- */
-
- void InitApp()
- {
- if(GoferInitialised)
- return;
-
- Init_Gofer_Windows();
-
- /* Find the Location of the Prelude file */
- findPrelude();
- InitPItems();
- clearProject();
-
- /* Restore numeric and string preferences */
- RestorePrefs(FALSE);
-
- GoferInitialised = TRUE;
-
- /*
- Initialise the Gofer interpreter.
- */
- init_gofer();
-
- /* Restore all preferences, including toggles */
- RestorePrefs(TRUE);
- InitOptionMenu();
-
- InterpreterInitialised = TRUE;
- }
-
- void OpenDoc(spec, filetype)
- FSSpec spec;
- OSType filetype;
- {
- if (filetype == texttype)
- doopenfile(p2cstr(spec.name),spec.vRefNum,spec.parID);
-
- else if (filetype == projtype)
- doreadproject(p2cstr(spec.name),spec.vRefNum,spec.parID);
-
- else if (filetype == preftype)
- dorestoreprefs(p2cstr(spec.name),spec.vRefNum,spec.parID,TRUE);
- }
-
- void PrintDoc(spec)
- FSSpec spec;
- {
- /* Print the given file */
- int windex = doopenforprint(p2cstr(spec.name),spec.vRefNum,spec.parID);
-
- if(windex != ILLEGAL_WINDOW)
- {
- Print_Window(windex);
- CloseAWindow(windex);
- }
- else
- SysBeep(2);
- }
-
- OSErr QuitApp(saveopt)
- DescType saveopt;
- {
- savemethod = saveopt;
- quit = Terminate_Gofer(); /* Quit */
- if (quit)
- return noErr;
- else
- {
- savemethod = kAEAskUser;
- return userCanceledErr;
- }
- }
-
- Init_Gofer()
- {
- ibeamcurs = GetCursor(iBeamCursor);
- watchcurs = GetCursor(watchCursor);
- gccurs = GetCursor(gcCursor);
- if(CCAvailable)
- gccursc = GetCCursor(gcCursor);
-
- if(!HasAppleEvents)
- {
- short count, msg;
- AppFile Params;
-
- windowtofront(worksheet);
-
- CountAppFiles(&msg,&count);
- if(msg==appOpen)
- InitApp();
-
- /* Handle initial open document/print requests */
- if(count > 0)
- {
- short i;
- FSSpec docSpec;
-
- for(i=1; i <= count; ++i)
- {
- GetAppFiles(i,&Params);
-
- if (getwdinfo(Params.vRefNum, &docSpec.vRefNum, &docSpec.parID) == noErr)
- pstrcopy(Params.fName, docSpec.name);
- else
- continue;
-
- /* Resolve an alias, perhaps */
- if(systemVersion >= 0x0700)
- {
- Boolean wasFolder, wasAliased;
- ResolveAliasFile(&docSpec,TRUE,&wasFolder,&wasAliased);
- }
-
- if(msg==appPrint)
- PrintDoc(docSpec);
- else
- OpenDoc(docSpec, Params.fType);
- }
-
- if(msg == appPrint)
- exit(0);
- }
- }
- }
-
-
- /*
- Draw a cursor appropriate to the current location.
- */
-
- void LocalToGlobalRect(Rect *theRect)
- /* Converts a rectangle from local coordinates to global coordinates */
- {
- Point topLeft, botRight;
-
- SetPt(&topLeft, theRect->left, theRect->top);
- LocalToGlobal(&topLeft);
- SetPt(&botRight, theRect->right, theRect->bottom);
- LocalToGlobal(&botRight);
-
- SetRect(theRect, topLeft.h, topLeft.v, botRight.h, botRight.v);
- }
-
- drawcursor(event, adjustRegion)
- EventRecord event;
- Boolean adjustRegion;
- {
- Rect worldRect;
-
- /* If we're in the background, or a DA is active, we don't need to fiddle with the cursor */
- if (!inForeground || (FrontWindow() != NIL && ((WindowPeek)FrontWindow())->windowKind < 0))
- return;
-
- /* Find the rectangle enclosing our virtual "world" if we need to calculate the cursor region */
- if (adjustRegion)
- {
- if (systemVersion >= 0x0410)
- worldRect = (**GetGrayRgn()).rgnBBox;
- else
- worldRect = qd.screenBits.bounds;
- }
-
- /* If we have an editable window, then we need to put up either an I-beam or an arrow cursor */
- if (thefrontwindow != ILLEGAL_WINDOW && isEditWindow(thefrontwindow))
- {
- Rect globalTextRect;
- GrafPtr saveport;
-
- GetPort(&saveport);
- SetPort(WINDOW(thefrontwindow));
-
- globalTextRect = (*TEHANDLE(thefrontwindow))->viewRect;
- LocalToGlobalRect(&globalTextRect);
-
- if (PtInRect(event.where, &globalTextRect))
- {
- SetCursor(*ibeamcurs);
- if (adjustRegion)
- RectRgn(cursorRgn, &globalTextRect);
- }
- else
- {
- SetCursor(&(qd.arrow));
- }
-
- SetPort(saveport);
- }
- /* If we don't have an editable window, then we just need an arrow */
- else
- {
- SetCursor(&(qd.arrow));
- if (adjustRegion)
- RectRgn(cursorRgn, &worldRect);
- }
- }
-
-
-
- safeexit(n)
- {
- mprintf("\n{{Gofer interpreter exited, code %d}}\n",n);
- longjmp(catch_error,n);
- }
-